package com.qymerge.manage.base.service.impl;

import com.qymerge.manage.base.dao.*;
import com.qymerge.manage.base.ro.*;
import com.qymerge.manage.base.service.IBDMProductionCostService;
import com.qymerge.manage.core.bean.ActionResultRO;
import com.qymerge.manage.core.bean.DataTableRO;
import com.qymerge.manage.core.bean.PageRequest;
import com.qymerge.manage.core.utils.DateUtil;
import com.qymerge.manage.core.utils.ReadExcelUtil;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.math.BigDecimal;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 *<p>Title: BDMVoucherServiceImpl</p>
 *<p>Description: </p>
 *
 *@Author cong.zhang
 *@Version 1.0.0
 *@Date 2020/12/19
 *@Time 17:53
 */
@Service
public class BDMProductionCostServiceImpl implements IBDMProductionCostService {

    @Autowired
    private IBDMProductionCostDao productionCostDao;
    @Autowired
    private IMetaCompanyDao metaCompanyDao;
    @Autowired
    private IMetaCostCenterDao metaCostCenterDao;
    @Autowired
    private IMetaAccountViewDao metaAccountViewDao;
    @Autowired
    private IMetaMaterialDao metaMaterialDao;

    /**
     * 用户管理-查询
     *
     * @param ro
     * @param pageRequest
     * @return
     */
    @Override
    public DataTableRO list(BDMProductionCostRO ro, PageRequest pageRequest) {
        List list = productionCostDao.list(ro, pageRequest);
        DataTableRO dataTableRO = new DataTableRO();
        int allCount = productionCostDao.total(ro);
        int pageSize = pageRequest.getSize();
        dataTableRO.setAll_count(allCount);
        dataTableRO.setList(list);
        dataTableRO.setCurrent_page(pageRequest.getPage());
        dataTableRO.setPage_size(pageSize);
        int allPage = (allCount % pageSize == 0 ? allCount / pageSize : allCount / pageSize + 1);
        dataTableRO.setAll_page(allPage);
        return dataTableRO;
    }

    /**
     * 详情
     *
     * @param id
     * @return
     */
    @Override
    public BDMProductionCostRO detail(Long id) {
        return productionCostDao.findOne(id);
    }

    @Override
    public ActionResultRO save(BDMProductionCostRO ro) {
        int rn = 0;
        if (ro.getId() == 0) {
            rn = productionCostDao.install(ro);
        } else {
            rn = productionCostDao.update(ro);
        }
        return new ActionResultRO(rn, ro.getId() == 0 ? "保存成功" : "修改成功", ro.getId() == 0 ? "保存失败" : "修改失败");
    }

    @Override
    public ActionResultRO importData(MultipartFile multipartFile, int flag) {
        StringBuffer tip = new StringBuffer("导入结果：<br/>");
        ReadExcelUtil readExcelUtil = new ReadExcelUtil();
        List<String[][]> datas = null;
        try {
            datas = readExcelUtil.readByStream(multipartFile.getInputStream(), 2, multipartFile.getOriginalFilename());
            if (org.springframework.util.CollectionUtils.isEmpty(datas)) {
                return new ActionResultRO(false, "execl数据为空");
            }
            String[][] data = datas.get(0);

            Long Id;                                    //
           String companyId= "";                        // 法人公司
           String companyName = "";                     // 法人公司

           String periodId= "";                         // 会计期间
           String periodYear = null;                    // 会计期间年

           String costCenterId= "";                    // 成本中心（部门）
           String costCenterCode= "";                  // 成本中心编码
           String costCenterName= "";                  // 成本中心名称

           String accountViewCode= "";                 // 科目代码（法人公司）
           String accountViewName= "";                 // 科目名称（法人公司）

           String materialCode= "";                    // 物料编码
           String materialName= "";                    // 物料名称

           BigDecimal stdPackQuantity=BigDecimal.ZERO;             // 标准箱规格
           String groupName="";                       // 产品分类
           String productionOrderNumber="";           // 生产订单号

           String workOrderCategory="";               // 工单类别
           Date productionDate=null;                    // 生成日期

           BigDecimal workHours=BigDecimal.ZERO;                   // 产线工时
           BigDecimal productionLineNumber=BigDecimal.ZERO;        // 产线人数
           BigDecimal totalWorkHours=BigDecimal.ZERO;              // 总工时
           BigDecimal productionQuantity=BigDecimal.ZERO;          // 生产数量
           BigDecimal directMaterial=BigDecimal.ZERO;              // 直接材料
           BigDecimal packaging=BigDecimal.ZERO;                   // 包装材料
           BigDecimal externalProcessingFee=BigDecimal.ZERO;       // 外协加工费
           BigDecimal labourCost=BigDecimal.ZERO;                  // 人工成本
           BigDecimal wastage=BigDecimal.ZERO;                     // 物耗
           BigDecimal energyCost=BigDecimal.ZERO;                  // 能源费
           BigDecimal depreciationAmortization=BigDecimal.ZERO;    // 折旧摊销
           BigDecimal administrativeExpenses=BigDecimal.ZERO;      // 办公费
           BigDecimal repairCharge=BigDecimal.ZERO;                // 修理费
           BigDecimal safeProductionReserve=BigDecimal.ZERO;       // 安全生产准备金
           BigDecimal extensiveRepair=BigDecimal.ZERO;             // 大修理
           BigDecimal totalCost=BigDecimal.ZERO;                   // 成本总额
           BigDecimal unitCost=BigDecimal.ZERO;                    // 单位成本

            List<BDMProductionCostRO> roNewList = new ArrayList<>();
            int rowNum = 1;        // 记录当前行
            int successNum = 0;    // 记录新增或者更新记录数
            int successNum11 = 0;    // 记录新增或者更新记录数
            for (String[] row : data) {
                rowNum++;

                companyName=row[0];
                periodYear=row[1];
                costCenterCode=row[2];
                costCenterName=row[3];
                accountViewCode=row[4];
                accountViewName=row[5];
                materialCode=row[6];
                materialName=row[7];
                if(StringUtils.isNotEmpty(row[8])){
                    stdPackQuantity= BigDecimal.valueOf(Double.valueOf(row[8]));
                }
                groupName=row[9];
                productionOrderNumber=row[10];
                workOrderCategory=row[11];

                try {
                    // 时间转换异常
                    String prductionDateStr = row[12];
                    if(StringUtils.isNotBlank(prductionDateStr)){
                        productionDate= DateUtil.parseDate(prductionDateStr);
                    };
                } catch (ParseException e) {
                    productionDate = null;
                }

                if(StringUtils.isNotEmpty(row[13])){workHours=BigDecimal.valueOf(Double.valueOf(row[13]));}
                if(StringUtils.isNotEmpty(row[14])){productionLineNumber=BigDecimal.valueOf(Double.valueOf(row[14]));}
                if(StringUtils.isNotEmpty(row[15])){totalWorkHours=BigDecimal.valueOf(Double.valueOf(row[15]));}
                if(StringUtils.isNotEmpty(row[16])){productionQuantity=BigDecimal.valueOf(Double.valueOf(row[16]));}
                if(StringUtils.isNotEmpty(row[17])){directMaterial=BigDecimal.valueOf(Double.valueOf(row[17]));}
                if(StringUtils.isNotEmpty(row[18])){packaging=BigDecimal.valueOf(Double.valueOf(row[18]));}
                if(StringUtils.isNotEmpty(row[19])){externalProcessingFee=BigDecimal.valueOf(Double.valueOf(row[19]));}
                if(StringUtils.isNotEmpty(row[20])){labourCost=BigDecimal.valueOf(Double.valueOf(row[20]));}
                if(StringUtils.isNotEmpty(row[21])){wastage=BigDecimal.valueOf(Double.valueOf(row[21]));}
                if(StringUtils.isNotEmpty(row[22])){energyCost=BigDecimal.valueOf(Double.valueOf(row[22]));}
                if(StringUtils.isNotEmpty(row[23])){depreciationAmortization=BigDecimal.valueOf(Double.valueOf(row[23]));}
                if(StringUtils.isNotEmpty(row[24])){administrativeExpenses=BigDecimal.valueOf(Double.valueOf(row[24]));}
                if(StringUtils.isNotEmpty(row[25])){repairCharge=BigDecimal.valueOf(Double.valueOf(row[25]));}
                if(StringUtils.isNotEmpty(row[26])){safeProductionReserve=BigDecimal.valueOf(Double.valueOf(row[26]));}
                if(StringUtils.isNotEmpty(row[27])){extensiveRepair=BigDecimal.valueOf(Double.valueOf(row[27]));}
                if(StringUtils.isNotEmpty(row[28])){totalCost=BigDecimal.valueOf(Double.valueOf(row[28]));}
                if(StringUtils.isNotEmpty(row[29])){unitCost=BigDecimal.valueOf(Double.valueOf(row[29]));}

                if (StringUtils.isEmpty(companyName + "")) {
                    tip.append("第").append(rowNum).append("行：公司数据为空，不予新增<br/>");
                    continue;
                }

                if (StringUtils.isEmpty(periodYear + "")) {
                    tip.append("第").append(rowNum).append("行：会计期间数据为空，不予新增<br/>");
                    continue;
                }

                MetaCompanyRO metaCompanyRO = metaCompanyDao.findOneByName(companyName);
                if (metaCompanyRO == null) {
                    tip.append("第").append(rowNum).append("行：关联公司不存在，不予新增 <br/>");
                    continue;
                } else {
                    companyId = metaCompanyRO.getId();
                }

                MetaCostCenterRO metaCostCenterRO = metaCostCenterDao.findOneByCode(costCenterCode);
                if (metaCostCenterRO == null) {
                    tip.append("第").append(rowNum).append("行：关联成本中心不存在，不予新增 <br/>");
                    continue;
                }

                MetaMaterialRO materialRO = metaMaterialDao.findOneByCode(materialCode);
                if (materialRO == null) {
                    tip.append("第").append(rowNum).append("行：关联产品编码不存在，不予新增 <br/>");
                    continue;
                }

                BDMProductionCostRO productionCostRO = new BDMProductionCostRO(companyId, companyName, periodYear, costCenterCode, costCenterName, accountViewCode, accountViewName, materialCode, materialName, stdPackQuantity, groupName, productionOrderNumber, workOrderCategory, productionDate, workHours, productionLineNumber, totalWorkHours, productionQuantity, directMaterial, packaging, externalProcessingFee, labourCost, wastage, energyCost, depreciationAmortization, administrativeExpenses, repairCharge, safeProductionReserve, extensiveRepair, totalCost, unitCost);
                roNewList.add(productionCostRO);
            }

            if (tip.toString().equals("导入结果：<br/>")){
                for (BDMProductionCostRO productionCostRO : roNewList) {
                    BDMProductionCostRO searchBDMProductionCostRORO = productionCostDao.findOneByCompanyNameAndPeriodYearAndCostCenterCodeAndMaterialCode(productionCostRO.getCompanyName(), productionCostRO.getPeriodYear(),productionCostRO.getCostCenterCode(), productionCostRO.getMaterialCode());
                    if (searchBDMProductionCostRORO != null) {
                        productionCostRO.setId(searchBDMProductionCostRORO.getId());
                        productionCostDao.update(productionCostRO);
                        successNum11++;
                    } else {
                        productionCostDao.install(productionCostRO);
                        successNum++;
                    }
                }
            }
            tip.append("成功更新记录：").append(successNum11).append("条 <br/>");
            tip.append("成功新增记录：").append(successNum).append("条 <br/>");
        } catch (IOException e) {
            e.printStackTrace();
            return new ActionResultRO(false, "导入失败");
        }

        return new ActionResultRO(true, tip.toString());
    }


}
